package se.webbzon.boltzmann.editor.component.dependencylist;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.Collection;
import java.util.Enumeration;

import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import se.webbzon.boltzmann.editor.comparator.WorldObjectComparator;
import se.webbzon.boltzmann.editor.component.AbstractComponent;
import se.webbzon.boltzmann.editor.list.InstanceListCell;
import se.webbzon.boltzmann.editor.list.SortedListModel;
import se.webbzon.boltzmann.editor.mvc.EditorModel;
import se.webbzon.oschi01.worldeditor.DeflatableWorldObject;
import se.webbzon.oschi01.worldobject.WorldObject;

public class DependencyDualList extends AbstractComponent {
	
	// Auto generated serial version UID
	private static final long serialVersionUID = 7923643396579196234L;
	
	// The lists in this panel
	private JList<WorldObject> instanceList, dependencyList; 
	
	/*============================================================
	Constructors
	============================================================*/
	
	public DependencyDualList(EditorModel model) {
		this(model,null);
	}
	
	public DependencyDualList(EditorModel model, WorldObject[] dependencies) {
		super("Dependencies");
		Dimension listDimension = new Dimension(256,320);
		
		// Generate world object list model
		SortedListModel<WorldObject> instanceListModel = 
				new SortedListModel<WorldObject>(	WorldObject.class,
													new WorldObjectComparator());
		Collection<WorldObject> instances = 
				model.getWorld().findInstances(WorldObject.class);
		for (WorldObject instance : instances)
			if (instance instanceof DeflatableWorldObject)
				instanceListModel.addElement(instance);
		
		// Generate dependency list model
		DefaultListModel<WorldObject> dependencyListModel =
				new DefaultListModel<WorldObject>();
		if (dependencies != null)
			for (WorldObject dependency : dependencies)
				dependencyListModel.addElement(dependency);
		
		instanceList = new JList<WorldObject>(instanceListModel);
		instanceList.setCellRenderer(new InstanceListCell());
		dependencyList = new JList<WorldObject>(dependencyListModel);
		dependencyList.setCellRenderer(new InstanceListCell());
		
		setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
		
		// Create from panel
		JPanel fromPanel = new JPanel();
		fromPanel.setLayout(new BoxLayout(fromPanel,BoxLayout.Y_AXIS));
		fromPanel.add(new JLabel("Available Instances:"));
		JScrollPane instanceScrollPane = new JScrollPane(instanceList);
		instanceScrollPane.setPreferredSize(listDimension);
		fromPanel.add(instanceScrollPane);
		add(fromPanel);
		
		// Create button panel
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.Y_AXIS));
		buttonPanel.add(new JButton(new AddAction()));
		buttonPanel.add(new JButton(new RemoveAction()));
		add(buttonPanel);
		
		// Create to panel
		JPanel toPanel = new JPanel();
		toPanel.setLayout(new BoxLayout(toPanel,BoxLayout.Y_AXIS));
		toPanel.add(new JLabel("Added Dependencies:"));
		JScrollPane dependencyScrollPane = new JScrollPane(dependencyList);
		dependencyScrollPane.setPreferredSize(listDimension);
		toPanel.add(dependencyScrollPane);
		add(toPanel);	
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns an enumeration of all the selected dependencies. **/
	public Enumeration<WorldObject> getDependencies() {
		return ((DefaultListModel<WorldObject>) 
				dependencyList.getModel()).elements();
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** An implementation of an abstract action used for the add button. **/
	private final class AddAction extends AbstractAction {
		
		// Auto generated serial version UID
		private static final long serialVersionUID = 4804733588510570097L;

		/*============================================================
		Constructors
		============================================================*/

		public AddAction() {
			putValue(AbstractAction.NAME,"Add >>");
		}
		
		/*============================================================
		Public Methods
		============================================================*/
		
		@Override public void actionPerformed(ActionEvent arg0) {
			WorldObject instance = instanceList.getSelectedValue();
			if (instance != null)
				((DefaultListModel<WorldObject>) dependencyList.getModel()).
					addElement(instance);
		}
		
	}
	
	/** An implementation of an abstract action used for the remove button. **/
	private final class RemoveAction extends AbstractAction {
		
		// Auto generated serial version UID
		private static final long serialVersionUID = 5929361005123835589L;

		/*============================================================
		Constructors
		============================================================*/

		public RemoveAction() {
			putValue(AbstractAction.NAME,"Remove (X)");
		}
		
		/*============================================================
		Public Methods
		============================================================*/
		
		@Override public void actionPerformed(ActionEvent arg0) {
			int index = dependencyList.getSelectedIndex();
			if (index >= 0)
				((DefaultListModel<WorldObject>) dependencyList.getModel()).remove(index);
		}
		
	}

}
